⚡ 30 秒速记
- 核心判断:源码会经历解析、编译与执行,执行上下文和调用栈决定变量解析、
this与函数返回的位置 - 原理主线:围绕 「执行上下文的创建」、「创建变量对象」、「建立作用域链」 建立输入、状态变化与输出之间的因果关系
- 文章范围:介绍了 JavaScript 引擎(以 V8 为例)执行 JavaScript 代码的全过程,包括语法分析、编译、执行阶段,解释了执行上下文、变量对象、作用域链、this 指向等核心原理,帮助读者深入理解 JavaScript 代码的运行机
- 边界与代价:规范中的词法环境不等同于某个引擎的具体内存对象,优化编译也可能随运行反馈去优化
- 工程落地:定位提升、暂时性死区、闭包和栈溢出时,要回到词法绑定与调用栈变化解释
JavaScript 代码会经历语法分析、编译和执行,执行上下文与调用栈共同决定变量查找、this 指向和函数返回位置。 编译阶段会创建变量对象、建立作用域链并确定 this,执行阶段再将上下文压入调用栈,结束后弹出。变量通过外部词法环境引用逐层查找,函数引用外层变量时,即使原上下文已销毁,相关变量对象仍可能因闭包留在内存中。具体分析时还要区分规范语义和引擎实现,并结合浏览器、Node.js 及其版本验证。
这篇文章不要按 API 清单来背。先用上面的 Mind Map 建立全局结构,再通过交互 DEMO 观察正常路径和边界路径如何改变状态;阅读正文时重点核对每一步的输入、负责执行的参与者、产生的中间状态以及最终可观察结果。遇到版本敏感结论,要把“历史实现”“当前行为”和“工程兼容策略”分开说明;遇到性能或架构取舍,则用实际指标、失败现象和验证手段支撑判断。
版本校准: 原理文章中的代码代表特定实现与写作时间。应用到当前项目时,应先确认浏览器、框架或工具的主版本,再区分稳定的规范语义、可变化的内部实现和项目自身约束。
在 V8 引擎中 JavaScript 代码的运行过程主要分成三个阶段
- 语法分析阶段。 该阶段会对代码进行语法分析,检查是否有语法错误(SyntaxError),如果发现语法错误,会在控制台抛出异常并终止执行
- 编译阶段。 该阶段会进行执行上下文(Execution Context)的创建,包括创建变量对象、建立作用域链、确定 this 的指向等。每进入一个不同的运行环境时,V8 引擎都会创建一个新的执行上下文。
- 执行阶段。 将编译阶段中创建的执行上下文压入调用栈,并成为正在运行的执行上下文,代码执行结束后,将其弹出调用栈
其中,语法分析阶段属于编译器通用内容,就不再赘述。前面提到的执行环境、词法环境、作用域、执行上下文等内容都是在编译和执行阶段中产生的概念。
JavaScript 在运行过程中会产生一个调用栈,调用栈遵循 LIFO(先进后出,后进先出)
# 执行上下文的创建
执行上下文的创建离不开 JavaScript 的运行环境,JavaScript 运行环境包括全局环境、函数环境和eval,其中全局环境和函数环境的创建过程如下